package com.haochang.chunkvod.app.database.hostess;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.haochang.chunkvod.app.database.order.OrderOpenHelper;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.DeleteBuilder;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.UpdateBuilder;
import com.j256.ormlite.stmt.Where;
import com.j256.ormlite.table.TableUtils;

import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;

/**
 *@author qintao
 *created at 2016/6/15 16:54
 * DB点餐数据
 */

public abstract class ReserveDaoManager<T>
{
	private final static Object gLock = new Object();

	protected OrderOpenHelper openHelper;

	public ReserveDaoManager(Context context)
	{

	}

	protected boolean openHelper()
	{
		openHelper = OrderOpenHelper.getHelper();

		if (openHelper == null || !openHelper.isOpen())
			return false;
		Log.d("DB", "Open Helper" + Thread.currentThread().getId());
		return true;
	}

	protected void closeHelper()
	{
		if (openHelper != null && openHelper.isOpen())
			openHelper.close();

		Log.d("DB", "Close Helper" + Thread.currentThread().getId());
	}

	/**
	 * 插入
	 * @param clazz
	 * @param t
	 */
	public int insert(Class<T> clazz, T t)
	{
		synchronized (gLock)
		{
			int value = -1;
			try
			{
				if (!openHelper() || clazz == null)
					return value;
				Dao<T, ?> dao = this.openHelper.getDao(clazz);
				if (dao != null)
				{
					value = dao.create(t);
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
			return value;
		}
	}

	public void insertAll(final Class<T> clazz, final List<T> t) throws Exception
	{
		synchronized (gLock)
		{
			try
			{
				if (!openHelper() || clazz == null || t == null)
					return;
				final Dao<T, ?> dao = this.openHelper.getDao(clazz);
				if (dao != null)
				{
					dao.callBatchTasks(new Callable<Boolean>()
					{
						public Boolean call() throws Exception
						{
							for (T t2 : t)
							{
								dao.create(t2);
							}
							return true;
						}
					});
				}

			} catch (SQLException e)
			{
			} finally
			{
				closeHelper();
			}
		}
	}

	/**
	 *
	 * 更新
	 *
	 */
	public void update(Class<T> clazz, T t)
	{
		synchronized (gLock)
		{
			try
			{
				if (!openHelper() || clazz == null || t == null)
				{
					return;
				}
				Dao<T, ?> dao = this.openHelper.getDao(clazz);
				if (dao != null)
				{
					dao.update(t);
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
		}
	}

	public void updateAll(final Class<T> clazz, final List<T> t) throws Exception
	{

		synchronized (gLock)
		{
			try
			{
				if (!openHelper() || clazz == null || t == null)
					return;
				final Dao<T, ?> dao = this.openHelper.getDao(clazz);
				if (dao != null)
				{
					dao.callBatchTasks(new Callable<Boolean>()
					{
						public Boolean call() throws Exception
						{
							for (T t2 : t)
							{
								dao.update(t2);
							}
							return true;
						}
					});
				}
			} catch (SQLException e)
			{
			} finally
			{
				closeHelper();
			}
		}
	}

	public void updateOrCreateAll(final Class<T> clazz, final List<T> t)
	{

		synchronized (gLock)
		{
			try
			{
				if (!openHelper() || clazz == null || t == null)
					return;
				final Dao<T, ?> dao = this.openHelper.getDao(clazz);
				if (dao != null)
				{
					dao.callBatchTasks(new Callable<Boolean>()
					{
						public Boolean call()
						{
							for (T t2 : t)
							{
								try
								{
									dao.createOrUpdate(t2);
								} catch (SQLException e)
								{
									e.printStackTrace();
									return false;
								}
							}
							return true;
						}
					});
				}
			} catch (SQLException e)
			{
			} catch (Exception e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
		}
	}

	public void updateOrCreate(final Class<T> clazz, final T t)
	{
		synchronized (gLock)
		{
			try
			{
				if (!openHelper() || clazz == null)
					return;
				final Dao<T, ?> dao = this.openHelper.getDao(clazz);
				if (dao != null)
				{
					dao.callBatchTasks(new Callable<Boolean>()
					{
						public Boolean call()
						{
							try
							{
								dao.createOrUpdate(t);
							} catch (SQLException e)
							{
								e.printStackTrace();
								return false;
							}
							return true;
						}
					});
				}
			} catch (SQLException e)
			{
			} catch (Exception e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
		}
	}

	/**
	 * 删除表数据 
	 * 传2个参数
	 */
	public void deleteBuilder(Class<T> clazz, String columnName, Object value, String columnName2, Object value2)
	{
		synchronized (gLock)
		{
			if (!openHelper() || clazz == null || TextUtils.isEmpty(columnName) || value == null || TextUtils.isEmpty(columnName2) || value == null)
				return;
			try
			{
				Dao<T, ?> dao = this.openHelper.getDao(clazz);
				if (dao != null)
				{
					DeleteBuilder<T, ?> deletekBuilder = dao.deleteBuilder();
					deletekBuilder.where().eq(columnName, value).and().eq(columnName2, value2);
					deletekBuilder.delete();
				}
			} catch (IllegalStateException ise)
			{
				ise.printStackTrace();
			} catch (SQLException e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
		}
	}

	public void updateBuilder(Class<T> clazz, String columnName, Object value, String columnName2, Object value2, String columnName3, Object value3,
			String columnName4, Object value4)
	{
		synchronized (gLock)
		{
			if (!openHelper() || clazz == null || TextUtils.isEmpty(columnName) || value == null || TextUtils.isEmpty(columnName2) || value2 == null
					|| TextUtils.isEmpty(columnName3) || value3 == null)
				return;
			try
			{
				Dao<T, ?> dao = this.openHelper.getDao(clazz);
				if (dao != null)
				{
					UpdateBuilder<T, ?> updateBuilder = dao.updateBuilder();
					updateBuilder.where().eq(columnName, value).and().eq(columnName2, value2).and().eq(columnName3, value3);
					updateBuilder.updateColumnValue(columnName4, value4);
				}
			} catch (IllegalStateException ise)
			{
				ise.printStackTrace();
			} catch (SQLException e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
		}
	}

	/**
	 * 删除表数据
	 * 传3个参数
	 */
	public void deleteBuilder(Class<T> clazz, String columnName, Object value, String columnName2, Object value2, String columnName3, Object value3)
	{
		synchronized (gLock)
		{
			if (!openHelper() || clazz == null || TextUtils.isEmpty(columnName) || value == null || TextUtils.isEmpty(columnName2) || value2 == null
					|| TextUtils.isEmpty(columnName3) || value3 == null)
				return;
			try
			{
				Dao<T, ?> dao = this.openHelper.getDao(clazz);
				if (dao != null)
				{
					DeleteBuilder<T, ?> deletekBuilder = dao.deleteBuilder();
					deletekBuilder.where().eq(columnName, value).and().eq(columnName2, value2).and().eq(columnName3, value3);
					deletekBuilder.delete();
				}
			} catch (IllegalStateException ise)
			{
				ise.printStackTrace();
			} catch (SQLException e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
		}
	}

	/**
	 * 删除表数据
	 * 传4个参数
	 */
	public void deleteBuilder(Class<T> clazz, String columnName, Object value, String columnName2, Object value2, String columnName3, Object value3,
			String columnName4, Object value4)
	{
		synchronized (gLock)
		{
			if (!openHelper() || clazz == null || TextUtils.isEmpty(columnName) || value == null || TextUtils.isEmpty(columnName2) || value2 == null
					|| TextUtils.isEmpty(columnName3) || value3 == null)
				return;
			try
			{
				Dao<T, ?> dao = this.openHelper.getDao(clazz);
				if (dao != null)
				{
					DeleteBuilder<T, ?> deletekBuilder = dao.deleteBuilder();
					deletekBuilder.where().eq(columnName, value).and().eq(columnName2, value2).and().eq(columnName3, value3).and().eq(columnName4, value4);
					deletekBuilder.delete();
				}
			} catch (IllegalStateException ise)
			{
				ise.printStackTrace();
			} catch (SQLException e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
		}
	}

	/**
	 *
	 * 删除
	 *
	 */

	public void deleteBuilder(Class<T> clazz, String columnName, Object value)
	{
		synchronized (gLock)
		{
			try
			{
				if (!openHelper() || clazz == null || TextUtils.isEmpty(columnName) || value == null)
					return;
				Dao<T, ?> dao = this.openHelper.getDao(clazz);
				if (dao != null)
				{
					DeleteBuilder<T, ?> deletekBuilder = dao.deleteBuilder();
					deletekBuilder.where().eq(columnName, value);
					deletekBuilder.delete();
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
		}
	}

	public void delete(Class<T> clazz, T t)
	{
		synchronized (gLock)
		{
			try
			{
				if (!openHelper() || clazz == null || t == null)
					return;
				Dao<T, ?> dao = this.openHelper.getDao(clazz);
				if (dao != null)
					dao.delete(t);

			} catch (SQLException e)
			{
			} finally
			{
				closeHelper();
			}
		}
	}

	public void delete(Class<T> clazz, Collection<T> t)
	{
		synchronized (gLock)
		{
			try
			{
				if (!openHelper() || clazz == null || t == null)
					return;
				Dao<T, ?> dao = this.openHelper.getDao(clazz);
				if (dao != null)
					dao.delete(t);
			} catch (SQLException e)
			{
			} finally
			{
				closeHelper();
			}
		}
	}

	/**
	 *
	 * 查询
	 *
	 */
	public List<T> queryAll(Class<T> clazz)
	{
		synchronized (gLock)
		{
			List<T> list = null;
			try
			{
				if (!openHelper() || clazz == null)
					return list;
				Dao<T, ?> dao = this.openHelper.getDao(clazz);
				if (dao != null)
					list = dao.queryForAll();
			} catch (SQLException e)
			{
			} finally
			{
				closeHelper();
			}
			return list;
		}
	}

	public T queryById(Class<T> clazz, Integer id)
	{
		synchronized (gLock)
		{
			T t = null;
			if (!openHelper() || clazz == null)
				return t;

			try
			{
				Dao<T, Integer> dao = this.openHelper.getDao(clazz);
				if (dao != null)
					t = dao.queryForId(id);
			} catch (SQLException e)
			{
			} finally
			{
				closeHelper();
			}
			return t;
		}
	}

	public T queryById(Class<T> clazz, String id)
	{
		synchronized (gLock)
		{
			T t = null;
			if (!openHelper() || TextUtils.isEmpty(id))
				return t;
			try
			{
				Dao<T, String> dao = openHelper.getDao(clazz);
				if (dao != null)
					t = dao.queryForId(id);
			} catch (SQLException e)
			{
			} finally
			{
				closeHelper();
			}
			return t;
		}
	}

	public T queryBuilder(Class<T> clazz, String columnName, Object value)
	{
		synchronized (gLock)
		{
			T t = null;
			if (!openHelper() || clazz == null || TextUtils.isEmpty(columnName) || value == null)
				return t;
			try
			{
				Dao<T, String> dao = openHelper.getDao(clazz);
				if (dao != null)
				{
					QueryBuilder<T, ?> queryBuilder = dao.queryBuilder();
					queryBuilder.where().eq(columnName, value);
					t = queryBuilder.queryForFirst();
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
			return t;
		}
	}

	public List<T> queryBuilderAll(Class<T> clazz, String columnName, Object value)
	{
		synchronized (gLock)
		{
			List<T> t = null;
			if (!openHelper() || clazz == null || TextUtils.isEmpty(columnName) || value == null)
				return t;
			try
			{
				Dao<T, String> dao = openHelper.getDao(clazz);
				if (dao != null)
				{
					QueryBuilder<T, ?> queryBuilder = dao.queryBuilder();
					queryBuilder.where().eq(columnName, value);
					t = queryBuilder.query();
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
			return t;
		}
	}

	public List<T> queryBuilderAll(Class<T> clazz, String columnName, Object value, String columnName2, Object value2)
	{
		synchronized (gLock)
		{
			List<T> t = null;
			if (!openHelper() || clazz == null || TextUtils.isEmpty(columnName) || value == null || TextUtils.isEmpty(columnName2) || value2 == null)
				return t;
			try
			{
				Dao<T, String> dao = openHelper.getDao(clazz);
				if (dao != null)
				{
					QueryBuilder<T, ?> queryBuilder = dao.queryBuilder();
					queryBuilder.where().eq(columnName, value).and().eq(columnName2, value2);
					t = queryBuilder.query();
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
			return t;
		}
	}

	public T queryBuilder(Class<T> clazz, String columnName1, Object value1, String columnName2, Object value2)
	{
		synchronized (gLock)
		{
			T t = null;
			if (!openHelper() || clazz == null || TextUtils.isEmpty(columnName1) || value1 == null || TextUtils.isEmpty(columnName2) || value2 == null)
				return t;
			try
			{
				Dao<T, String> dao = openHelper.getDao(clazz);
				if (dao != null)
				{
					QueryBuilder<T, ?> queryBuilder = dao.queryBuilder();
					queryBuilder.where().eq(columnName1, value1).and().eq(columnName2, value2);
					//				queryBuilder.where().like(columnName1, value1).or().like(columnName2, value2);
					t = queryBuilder.queryForFirst();
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
			return t;
		}
	}

	public T queryBuilder(Class<T> clazz, String columnName1, Object value1, String columnName2, Object value2, String columnName3, Object value3)
	{
		synchronized (gLock)
		{
			T t = null;
			if (!openHelper() || clazz == null || TextUtils.isEmpty(columnName1) || value1 == null || TextUtils.isEmpty(columnName2) || value2 == null
					|| TextUtils.isEmpty(columnName3) || value3 == null)
				return t;
			try
			{
				Dao<T, String> dao = openHelper.getDao(clazz);
				if (dao != null)
				{
					QueryBuilder<T, ?> queryBuilder = dao.queryBuilder();
					queryBuilder.where().eq(columnName1, value1).and().eq(columnName2, value2).and().eq(columnName3, value3);
					//				queryBuilder.where().like(columnName1, value1).or().like(columnName2, value2);
					t = queryBuilder.queryForFirst();
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
			return t;
		}
	}

	public T queryBuilder(Class<T> clazz, String columnName1, Object value1, String columnName2, Object value2, String columnName3, Object value3,
			String columnName4, Object value4, String columnName5, Object value5)
	{
		synchronized (gLock)
		{
			T t = null;
			if (!openHelper() || clazz == null || TextUtils.isEmpty(columnName1) || value1 == null || TextUtils.isEmpty(columnName2) || value2 == null
					|| TextUtils.isEmpty(columnName3) || value3 == null || TextUtils.isEmpty(columnName4) || value4 == null)
				return t;
			try
			{
				Dao<T, String> dao = openHelper.getDao(clazz);
				if (dao != null)
				{
					QueryBuilder<T, ?> queryBuilder = dao.queryBuilder();
					queryBuilder.where().eq(columnName1, value1).and().eq(columnName2, value2).and().eq(columnName3, value3).and().eq(columnName4, value4).and()
							.eq(columnName5, value5);
					t = queryBuilder.queryForFirst();
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
			return t;
		}
	}

	/**
	 * 清除表
	 */

	public void clearTable(Class<T> clazz)
	{
		synchronized (gLock)
		{
			if (!openHelper() || clazz == null)
				return;
			try
			{
				Dao<T, String> dao = openHelper.getDao(clazz);
				if (dao != null)
					TableUtils.clearTable(dao.getConnectionSource(), clazz);
			} catch (SQLException e)
			{
				e.printStackTrace();
			} finally
			{
				closeHelper();
			}
		}

	}

	public void clearTable(List<Class<T>> classes)
	{
		if (classes != null && !classes.isEmpty())
		{
			for (int i = 0; i < classes.size(); i++)
			{
				clearTable(classes.get(i));
			}
		}
	}

	protected long getCount(Class<T> clazz, String columnName, int columnValue, int columnValue1)
	{
		long returnValue = 0;
		synchronized (gLock)
		{
			if (!openHelper() || clazz == null)
				return returnValue;
			try
			{
				Dao<T, String> dao = openHelper.getDao(clazz);
				if (dao != null)
				{
					QueryBuilder<T, ?> queryBuilder = dao.queryBuilder();
					queryBuilder.where().eq(columnName, columnValue).or().eq(columnName, columnValue1);
					returnValue = queryBuilder.countOf();
				}
			} catch (SQLException e)
			{
				returnValue = 0;
			} finally
			{
				closeHelper();
			}
		}
		return returnValue;
	}

	/**
	 * 查询符合记录的条数
	 * @param clazz
	 * @param columnName
	 * @param value
	 * @param columnName2
	 * @param value2
	 * @return
	 */
	public long queryCount(Class<T> clazz, String columnName, Object value, String columnName2, Object value2)
	{
		synchronized (gLock)
		{
			long count = 0;
			if (!openHelper() || clazz == null)
				return count;
			try
			{
				Dao<T, ?> dao = this.openHelper.getDao(clazz);
				if (dao != null)
				{
					QueryBuilder<T, ?> queryBuilder = dao.queryBuilder();
					Where<T, ?> where = queryBuilder.where();
					where.eq(columnName, value).and().eq(columnName2, value2);
					count = queryBuilder.countOf();
				}
			} catch (IllegalStateException ise)
			{
				ise.printStackTrace();
			} catch (SQLException e)
			{
			} finally
			{
				closeHelper();
			}
			return count;
		}
	}

}
